#include "dlist.h"  // 关键修正：添加 # 符号，正确引入链表头文件（之前缺失 #）
#include <stdio.h>   // 可选：如需打印调试信息可包含

// 1. 初始化双向链表
DList* dlist_init() {
    // 为链表结构体分配内存
    DList* list = (DList*)malloc(sizeof(DList));
    if (list == NULL) {
        fprintf(stderr, "dlist_init: 链表内存分配失败\n");
        return NULL;
    }
    // 初始化链表状态（空链表）
    list->head = NULL;  // 头节点为空
    list->tail = NULL;  // 尾节点为空
    list->size = 0;     // 节点数量为 0
    return list;
}

// 2. 向链表尾部添加节点
void dlist_append(DList* list, void* data) {
    // 非法参数检查（避免空指针访问）
    if (list == NULL || data == NULL) {
        fprintf(stderr, "dlist_append: 链表或数据为空\n");
        return;
    }

    // 为新节点分配内存
    DListNode* new_node = (DListNode*)malloc(sizeof(DListNode));
    if (new_node == NULL) {
        fprintf(stderr, "dlist_append: 节点内存分配失败\n");
        return;
    }

    // 初始化新节点数据和指针
    new_node->data = data;    // 存储用户数据
    new_node->prev = list->tail;  // 新节点前驱指向原尾节点
    new_node->next = NULL;    // 新节点后继为空（尾部节点）

    // 处理链表为空的情况
    if (list->size == 0) {
        list->head = new_node;  // 空链表时，新节点既是头也是尾
    } else {
        list->tail->next = new_node;  // 非空链表时，原尾节点后继指向新节点
    }
    list->tail = new_node;  // 更新链表尾节点为新节点
    list->size++;           // 链表长度 +1
}

// 3. 从链表中移除指定数据的节点
void dlist_remove(DList* list, void* data) {
    // 非法参数检查
    if (list == NULL || data == NULL || list->size == 0) {
        fprintf(stderr, "dlist_remove: 链表为空或数据无效\n");
        return;
    }

    // 遍历链表查找目标节点
    DListNode* curr_node = list->head;
    while (curr_node != NULL) {
        // 找到存储目标数据的节点
        if (curr_node->data == data) {
            // 调整前驱节点的后继指针
            if (curr_node->prev != NULL) {
                curr_node->prev->next = curr_node->next;
            } else {
                list->head = curr_node->next;  // 移除的是头节点，更新头
            }

            // 调整后继节点的前驱指针
            if (curr_node->next != NULL) {
                curr_node->next->prev = curr_node->prev;
            } else {
                list->tail = curr_node->prev;  // 移除的是尾节点，更新尾
            }

            // 释放目标节点内存
            free(curr_node);
            list->size--;  // 链表长度 -1
            return;  // 假设数据唯一，找到后直接返回
        }
        curr_node = curr_node->next;  // 移动到下一个节点
    }

    // 未找到目标数据时提示（可选）
    fprintf(stderr, "dlist_remove: 未找到指定数据的节点\n");
}

// 4. 销毁整个链表（释放所有内存）
void dlist_destroy(DList* list) {
    if (list == NULL) {
        return;
    }

    // 遍历释放所有节点内存
    DListNode* curr_node = list->head;
    while (curr_node != NULL) {
        DListNode* next_node = curr_node->next;  // 先保存下一个节点（避免释放后丢失）
        free(curr_node);                         // 释放当前节点
        curr_node = next_node;                   // 移动到下一个节点
    }

    // 释放链表结构体本身的内存
    free(list);
}

// 5. 获取链表当前长度（节点数量）
int dlist_get_size(DList* list) {
    if (list == NULL) {
        return 0;  // 空链表返回 0
    }
    return list->size;
}

// 6. 遍历链表（调用回调函数处理每个节点数据）
void dlist_traverse(DList* list, void (*callback)(void* data)) {
    // 非法参数检查（链表为空或回调函数未定义）
    if (list == NULL || callback == NULL) {
        fprintf(stderr, "dlist_traverse: 链表或回调函数无效\n");
        return;
    }

    // 遍历链表，对每个节点调用回调函数
    DListNode* curr_node = list->head;
    while (curr_node != NULL) {
        callback(curr_node->data);  // 执行用户定义的回调逻辑
        curr_node = curr_node->next;
    }
}
